package edu.sfsu.powerrangers.jeopardy.editor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import edu.sfsu.powerrangers.jeopardy.gamestate.*;

public class GameWriter {
	public void writeGames(File gameFile, Game[] games) {
		try {
			PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(gameFile), "UTF-8"), true);
			out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			out.println("<!DOCTYPE game PUBLIC \"-//Kreative//DTD WTQ 1.0//EN\" \"wtq.dtd\">");
			for (Game game : games) {
				writeGame(out, game);
			}
			out.close();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}
	
	private void writeGame(PrintWriter out, Game game) {
		out.println("<game>");
		out.println("\t<name>" + htmlify(game.getName()) + "</name>");
		out.println("\t<description>" + htmlify(game.getDescription()) + "</description>");
		for (Round round : game) {
			writeRound(out, round);
		}
		if (game.getFinalRound() != null) {
			writeFinalRound(out, game.getFinalRound());
		}
		out.println("</game>");
	}
	
	private void writeRound(PrintWriter out, Round round) {
		out.println("\t<round>");
		for (Category category : round) {
			writeCategory(out, category);
		}
		out.println("\t</round>");
	}
	
	private void writeCategory(PrintWriter out, Category category) {
		out.println("\t\t<category>");
		out.println("\t\t\t<name>" + htmlify(category.getCategoryName()) + "</name>");
		for (Clue clue : category) {
			writeClue(out, clue);
		}
		out.println("\t\t</category>");
	}
	
	private void writeClue(PrintWriter out, Clue clue) {
		out.println("\t\t\t<clue>");
		out.println("\t\t\t\t<value>" + Integer.toString(clue.getValue()) + "</value>");
		if (clue.isDouble()) out.println("\t\t\t\t<double/>");
		out.println("\t\t\t\t<text>" + htmlify(clue.getClue()) + "</text>");
		out.println("\t\t\t\t<response>" + htmlify(clue.getResponse()) + "</response>");
		out.println("\t\t\t</clue>");
	}
	
	private void writeFinalRound(PrintWriter out, FinalRound round) {
		out.println("\t<finalround>");
		out.println("\t\t<name>" + htmlify(round.getCategoryName()) + "</name>");
		out.println("\t\t<text>" + htmlify(round.getClue()) + "</text>");
		out.println("\t\t<response>" + htmlify(round.getResponse()) + "</response>");
		out.println("\t</finalround>");
	}
	
	private String htmlify(String in) {
		CharacterIterator it = new StringCharacterIterator(in);
		StringBuffer out = new StringBuffer();
		for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
			switch (ch) {
			case '&': out.append("&amp;"); break;
			case '<': out.append("&lt;"); break;
			case '>': out.append("&gt;"); break;
			case '\"': out.append("&quot;"); break;
			case '\'': out.append("&#39;"); break;
			case '\u00A0': out.append("&nbsp;"); break;
			default:
				if (ch < 32 || ch >= 127) {
					out.append("&#"+(int)ch+";");
				} else {
					out.append(ch);
				}
				break;
			}
		}
		return out.toString();
	}
}
